package cn.ac.iie.kgmanager.service.impl;

import cn.ac.iie.kgmanager.dao.NodeDao;
import cn.ac.iie.kgmanager.domain.Node;
import cn.ac.iie.kgmanager.dto.Page;
import cn.ac.iie.kgmanager.dto.request.GraphRelation;
import cn.ac.iie.kgmanager.service.GraphService;
import cn.ac.iie.kgmanager.service.NodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName GraphServiceImpl
 * @Author tjh
 * @Date 19/6/13 下午3:37
 * @Version 1.0
 **/
@Service(value = "graphService")
@Slf4j
public class GraphServiceImpl implements GraphService {
    @Autowired
    NodeService nodeService;
    @Autowired
    NodeDao nodeDao;
    @Override
    public List<Node> getIdsByRelation(String id, List<GraphRelation> relations) {
        ExecutorService fixed = Executors.newCachedThreadPool();

        List<Node> ids = new Vector<>();
        if (relations != null && !relations.isEmpty()) {
            // 根据id查周边节点
            for (GraphRelation relation : relations) {
                Set<String> labels = relation.getLabels();
                Integer nodeNum = relation.getNodeNum();
                List<GraphRelation> innerRelations = relation.getRelations();

                fixed.execute(() -> {
                    Page<Node> aroundNodes = nodeService.getAroundNodes(id, labels, 1, nodeNum == null ? null : 1, nodeNum);

                    for (Node aroundNode : aroundNodes) {
                        ids.addAll(getIdsByRelation(aroundNode.getId(), innerRelations));
                    }

                });
            }
        }

        ids.add(nodeService.getNodeById(id));

        fixed.shutdown();
        while (true) {
            if(fixed.isTerminated()) {
                break;
            }
        }
        return ids;
    }

    @Override
    public List<Node> getIdsByRelation(String sourceId, Set<String> firstLabels, Set<String> secondLabels) {
        return nodeDao.getLevelsNodes(sourceId, firstLabels, secondLabels);

    }
}
